import { createContext, useContext } from 'react';
import { configure } from 'mobx';
import userStore from './UserStore';
import { observer } from 'mobx-react';
import { mobxFactory } from 'utils/mobxFactory';

import { autoExport } from 'utils/misc';

/**
 * 生成 store 名字
 * 例：
 *     path:  '/page/home' return: 'home'
 *     path: '/foo-bar'    return 'fooBar'
 * @param str
 * @returns {*}
 */
const getStoreName = (str) => {
  str = str.replace(/-(\w)/g, (_, a) => a.toUpperCase());
  const pathArray = str.split('/');
  return pathArray[pathArray.length - 2];
};

// 收集 page 文件夹下所有以 module.js 结尾的文件。
const moduleFiles = require.context('page', true, /module\.js/);
const modules = autoExport(moduleFiles, getStoreName);

configure({
  enforceActions: 'always',
});

const Stores = {
  userStore,
  ...modules,
};

export const storeContext = createContext(mobxFactory(Stores));

/**
 * 用 react context 注入store
 * 使用：
 *    useStore('userStore')
 */
export const useStore = (name) => (name ? useContext(storeContext)[name] : useContext(storeContext));

/**
 * 用高阶组件注入 store。
 * 使用：
 *    1. @inject((root) => ({userStore: root.userStore}))
 *    2. inject((root) => ({userStore: root.userStore}))(ReactComponent)
 * @param selector
 * @returns {function(WrappedComponent): function(*=): *}
 */
export const inject = (selector) => (WrappedComponent) => {
  const WrapperComponent = (props = {}) => {
    const root = useContext(storeContext);
    const newProps = { ...selector(root), ...props };
    return <WrappedComponent {...newProps} />;
  };
  WrapperComponent.displayName = WrappedComponent.name;
  return observer(WrapperComponent);
};

export default Stores;
